// 经验：
// 1. 标签后面不能有空格等，只能是冒号
// 2. rtr 执行的时候会产生单步异常，导致脚本不能继续自动执行，需要手动执行。
// 3. 对于输出参数，如何是野指针，可以直接访问，也不会崩溃。所以不必用mem.valid
// 4. mem.valid有失败的时候，不可控，尽量不依赖这个函数，直接访问不会崩溃
// 5. arg.get(0)访问参数和[esp+4] 是一样，在任何调用约定的函数头和函数尾部都可以用，因为在所有约定的函数尾部正好调用栈和函数入口一样，stdcall的在最后的"ret n"下断点也行。
//	  因为会先执行断点处的脚本，再执行"ret n"这条指令。
// 6. 给API下断点，kernel32的函数尽量下到kernelbase.dll中。
// 7. 脚本的断点下了以后，后面的在脚本断点中间间隔的手动断点可能无法停下来。或者是在 rtr 过程中的断点无法停下来。需要测试。
//   如果是这样，可以采用在函数头尾分别下断点的方法。也可以尝试在需要断点下来的位置加msg弹框。
// 8. 所有脚本断点启动之前，如果有断点，可能导致脚本断点无法执行。
// 9. 禁用、启用、删除断点 bpd bpe bpc 这三个命令 的参数只能是地址，不能是断点的名字
// 10. 只要脚本执行过程中，遇到手动的断点，那么这个脚本后面无法自动运行。这导致SetBreakpointCommand不适合大范围使用。可以在需要断点的地方用msgbox，这样估计能继续执行脚本



// 给API下断点
// 标签的位置，lable的位置，冒号后面不能有空格，否则不识别这个标签

bp KernelBase.CreateFileW, "CreateFileW Start"
SetBreakpointCommand KernelBase.CreateFileW, "scriptcmd call cbForCreateFileW"


bp KernelBase+118C51, "CreateFileW End"
SetBreakpointCommand KernelBase+118C51, "scriptcmd call cbForCreateFileWEnd"
labelset KernelBase+118C51 , "CreateFileW End"


bp KernelBase.GetQueuedCompletionStatus, "GetQueuedCompletionStatus Start"
SetBreakpointCommand KernelBase.GetQueuedCompletionStatus, "scriptcmd call cbForGetQueueCompletionStatus"


bp KernelBase+14473D , "GetQueuedCompletionStatus End"
SetBreakpointCommand KernelBase+14473D, "scriptcmd call cbForGetQueueCompletionStatusEnd"
labelset KernelBase+14473D , "GetQueuedCompletionStatus End"



bp KernelBase.PostQueuedCompletionStatus, "PostQueuedCompletionStatus Start"
SetBreakpointCommand KernelBase.PostQueuedCompletionStatus, "scriptcmd call cbForPostQueuedCompletionStatus"


bp KernelBase+143FB9, "PostQueuedCompletionStatus End"
SetBreakpointCommand KernelBase+143FB9, "scriptcmd call cbForPostQueuedCompletionStatusEnd"
labelset KernelBase+143FB9 , "PostQueuedCompletionStatus End"



bp KernelBase.CreateIoCompletionPort, "CreateIoCompletionPort Start"
SetBreakpointCommand KernelBase.CreateIoCompletionPort, "scriptcmd call cbForCreateIoCompletionPort"


bp KernelBase+144885, "CreateIoCompletionPort End"
SetBreakpointCommand KernelBase+144885, "scriptcmd call cbForCreateIoCompletionPortEnd"
labelset KernelBase+144885 , "CreateIoCompletionPort End"

// 给主模块RVA下断点
bp mod.main()+47E095A, "test main bp"

// 禁用断点
bpd KernelBase.CreateIoCompletionPort

// 启用断点
bpe KernelBase.CreateIoCompletionPort


// 删除断点
bpc mod.main()+47E095A



goto main


cbForCreateFileW:
   //log filePath={ansi(arg.get(0))}
   log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateFileW Start ...  filePath={utf16(arg.get(0))}, parm2={arg.get(1)}, parm3={arg.get(2)}, callAddr={[esp]}"
   //rtr
   //log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateFileW End ...   filePath={utf16(arg.get(0))}, parm2={arg.get(1)}, parm3={arg.get(2)},ret_hFile={eax}"
   goto main
   
   
cbForCreateFileWEnd:
   log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateFileW End ...   filePath={utf16(arg.get(0))}, parm2={arg.get(1)}, parm3={arg.get(2)},ret_hFile={eax}"
   goto main
   
   
  
cbForGetQueueCompletionStatus:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus start ... CompletionPort={[esp+4]}，pNumOfTransed={[esp+8]}，lpCompletionKey={[esp+c]}，lpOverlapped={[esp+10]}，dwMilliseconds={[esp+14]}，callAddr={[esp]}"
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus start2 ... *pNumOfTransed={[arg.get(1)]}，*lpCompletionKey={[arg.get(2)]}，*lpOverlapped={arg.get(3)}，dwMilliseconds={arg.get(4)}，retValue={eax}"
	//rtr
	//log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus End ... *pNumOfTransed={[arg.get(1)]}，*lpCompletionKey={[arg.get(2)]}，*lpOverlapped={[arg.get(3)]}，dwMilliseconds={arg.get(4)}，retValue={eax}"
	//log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus End2 ...  NumOfTransed={[[esp+8]]}, CompletionKey={[[esp+c]]}，Overlapped={[[esp+10]]}, ret ={eax}，"
	goto main
	


cbForGetQueueCompletionStatusEnd:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus End ... *pNumOfTransed={[[arg.get(1)]]}，*lpCompletionKey={[[arg.get(2)]]}，*lpOverlapped={[[arg.get(3)]]}，dwMilliseconds={arg.get(4)}，retValue={eax}"
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}:  GetQueuedCompletionStatus End2 ...  NumOfTransed={[[[esp+8]]]}, CompletionKey={[[[esp+c]]]}，Overlapped={[[esp+10]]}, ret ={eax}，"
	goto main
	
	
	
cbForPostQueuedCompletionStatus:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueuedCompletionStatus start ... CompletionPort={arg.get(0)}，numTransfer={arg.get(1)}，dwCompletionKey={arg.get(2)}，lpOverlapped={arg.get(3)}，callAddr={[esp]}"
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueuedCompletionStatus start2 ...  CompletionPort={[esp+4]}，numTransfer={[esp+8]}，dwCompletionKey={[esp+c]}，lpOverlapped={[esp+10]}，callAddr={[esp]}"
	//rtr
	//log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueuedCompletionStatus End ... retValue={eax}"
	goto main
	
	

cbForPostQueuedCompletionStatusEnd:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: PostQueuedCompletionStatus End ... retValue={eax}"
	goto main
	
	

cbForCreateIoCompletionPort:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort start ... FileHandle={[esp+4]}，ExistingPort={[esp+8]}，dwCompletionKey={[esp+c]}，NumberOfConcurrentThreads={[esp+10]}，callAddr={[esp]}"
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort start2 ... FileHandle={arg.get(0)}，ExistingPort={arg.get(1)}，dwCompletionKey={arg.get(2)}，NumberOfConcurrentThreads={arg.get(3)}，callAddr={[esp]}"
	//rtr 
	//log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort End ... retValue={eax}"
	goto main
	
	
cbForCreateIoCompletionPortEnd:
	log "tid={tid()} time={GetTickCount()} RVA={mod.rva(eip)}: CreateIoCompletionPort End ... retValue={eax}"
	goto main


main:
	run
	
	
ret